#include "StdAfx.h"
#include "VSqlMeta.h"

// VSqlMetaColumn /////////////////////////////////////////////////////////////

//
QString VSqlMetaColumn::displayName() const 
{ 
	return m_type == EType_node 
		? QString("node.") + m_field.name() 
		: QString("item.") + m_field.name();
}

// VSqlMetaColumnList /////////////////////////////////////////////////////////

//
VSqlMetaColumnList::VSqlMetaColumnList()
	:m_colDisplayName(-1)
	,m_colItemType(-1)
	,m_colKeyNameUpper(-1)
	,m_colItem_refIdItem(-1)
{
	VSqlMeta meta;
	int colField = 0;
	foreach (const QSqlField field,meta.node().fieldList())
	{
		VSqlMetaColumn col;
		col.setType(VSqlMetaColumn::EType_node);
		col.setField(field,colField++);
		append(col);
	}

	colField = 0;
	foreach (const QSqlField field,meta.item().fieldList())
	{
		VSqlMetaColumn col;
		col.setType(VSqlMetaColumn::EType_item);
		col.setField(field,colField++);
		append(col);
	}

	m_colDisplayName = indexOf(VSqlMetaColumn::EType_item,meta.item().displayName().name());
	Q_ASSERT(m_colDisplayName >= 0);
	swap(0,m_colDisplayName);
	m_colDisplayName = 0;


	m_colNode_idNode = indexOf(VSqlMetaColumn::EType_node,meta.node().idNode().name());
	Q_ASSERT(m_colNode_idNode >= 0);

	m_colNode_refIdItem = indexOf(VSqlMetaColumn::EType_node,meta.node().refIdItem().name());
	Q_ASSERT(m_colNode_refIdItem >= 0);

	m_colNode_refIdRec = indexOf(VSqlMetaColumn::EType_node,meta.node().refIdRec().name());
	Q_ASSERT(m_colNode_refIdRec >= 0);

	m_colItemType = indexOf(VSqlMetaColumn::EType_item,meta.item().itemType().name());
	Q_ASSERT(m_colItemType >= 0);

	m_colKeyNameUpper = indexOf(VSqlMetaColumn::EType_item,meta.item().keyNameUpper().name());
	Q_ASSERT(m_colKeyNameUpper >= 0);

	m_colItem_refIdItem = indexOf(VSqlMetaColumn::EType_item,meta.item().refIdItem().name());
	Q_ASSERT(m_colKeyNameUpper >= 0);
}

//
int VSqlMetaColumnList::indexOf(VSqlMetaColumn::EType type,const QString &fieldName) const
{
	int index = 0;

	foreach (const VSqlMetaColumn c,*this)
	{
		if (c.type() == type && c.field().name() == fieldName)
			return index;

		index++;
	}

	return -1;
}

// VSqlMetaRecord ///////////////////////////////////////////////////////////

//
void VSqlMetaRecord::clear() 
{ 
	m_node.clear(); 
	m_item.clear();
	//qDeleteAll(m_children);
	m_children.clear();
	m_parent = NULL;
}

//
void VSqlMetaRecord::setRecord(const VSqlMetaRecord *v) 
{ 
	if (v)
	{
		m_item = v->m_item;
		m_node = v->m_node;
	}
	else
	{
		m_item.clear();
		m_node.clear();
	}
}

//
bool VSqlMetaRecord::hasChildren(const QSqlDatabase &db)
{ 
	if (m_hasChildren)
		return true;

	VSqlNode node;
		node.setValues(m_node);
	VSqlNode_hasChildren hasChildren(db);
	m_hasChildren = hasChildren.exec(node.idNode().value());
	return m_hasChildren;
}

//
void VSqlMetaRecord::clearChildren()
{
	//qDeleteAll(m_children);
	m_children.clear();
	m_hasChildren = false;
}

//
void VSqlMetaRecord::setChildren(const QList<VSqlMetaRecord*> &v) 
{ 
	clearChildren();
	m_children = v;
	m_hasChildren = v.count() > 0;
	
	foreach (VSqlMetaRecord *child,m_children)
		child->m_parent = this;
}
/****************
//
void VSqlMetaRecord::appendChild(VSqlMetaRecord *child)
{
	child->m_parent = this;
	m_children.append(child);
	m_hasChildren = true;
}
*****************/
//
void VSqlMetaRecord::insertChild(int row,VSqlMetaRecord *child)
{
	child->m_parent = this;
	m_children.insert(row,child);
	m_hasChildren = true;
}


//
int VSqlMetaRecord::row() const
{
	if (m_parent)
		return m_parent->m_children.indexOf(const_cast<VSqlMetaRecord*>(this));

	return 0;

/**********
	VSqlNode thisNode;
		thisNode.setValues(m_node);
		
	int index = 0;
	
	if (parentRecord)	foreach (VSqlMetaRecord *p,parentRecord->m_children)
	{
		VSqlNode childNode;
			childNode.setValues(p->m_node);
			
		if (p == this)
			return index;
		
		index++;
	}

	return 0;
***************/	
}

//
QVariant VSqlMetaRecord::data(int column,const VSqlMetaColumnList &columnList) const
{
	const VSqlMetaColumn col = columnList[column];

	switch (col.type())
	{
		case VSqlMetaColumn::EType_node: return (*m_node)[col.colField()];
		case VSqlMetaColumn::EType_item: return (*m_item)[col.colField()];
	}

	Q_ASSERT(false);
	return QVariant();
}

//
void VSqlMetaRecord::setData(int column,const VSqlMetaColumnList &columnList,const QVariant &value)
{
	const VSqlMetaColumn col = columnList[column];

	switch (col.type())
	{
		case VSqlMetaColumn::EType_node: (*m_node)[col.colField()] = value; return;
		case VSqlMetaColumn::EType_item: (*m_item)[col.colField()] = value; return;
	}

	Q_ASSERT(false);
}

// VSqlMeta ///////////////////////////////////////////////////////////////////

//
void VSqlMeta::setValues(const VSqlMetaRecord *r)
{
	m_node.setValues(r->node()); 
	m_item.setValues(r->item());
}

//
void VSqlMeta::setRecord(VSqlMetaRecord *r) const
{
	m_node.setRecord(r->node()); 
	m_item.setRecord(r->item()); 
}
